﻿using UnityEngine;
using System.Collections;
using System.Net;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace ZWFrameWork
{
    public class MyTypeAttribute : Attribute
    {
        public MyTypeAttribute(int pet)
        {
            thePet = pet;
        }

        protected int thePet;

        public int Pet
        {
            get { return thePet; }
            set { thePet = Pet; }
        }
    }
    
    
    /// <summary>
    /// 网络层工具类 
    /// </summary>
    public class NetUtils
    {
        public static byte[] UTF8ToUTF16(string utf8string, int backLength)
        {
            if (string.IsNullOrEmpty(utf8string) || string.IsNullOrWhiteSpace(utf8string))
            {
                GameUtilty.Error("utf8string is null or empty");
                return null;
            }

            byte[] key = new byte[backLength];
            byte[] bytearray_unicode = Encoding.Unicode.GetBytes(utf8string);
            int count = 0;
            int length = bytearray_unicode.Length;
            int returnlength = backLength >= length ? length : backLength;
            for (int i = 0; i < returnlength; i++)
            {
                key[i] = bytearray_unicode[i];
                count++;
            }

            return key;
        }

        /// <summary>
        /// 将16进制字节转换为string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string UTF16ByteArrayToString(byte[] data)
        {
            if (data == null)
            {
                GameUtilty.Error("data is null!");
                return "";
            }

            byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, data);
            return ByteArrayToString(utf8Bytes);
        }

        /// <summary>
        /// 将字节数组转换为string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteArrayToString(byte[] data)
        {
            if (data == null)
            {
                GameUtilty.Error("data is null!");
                return "";
            }

            return System.Text.Encoding.UTF8.GetString(data).Trim('\0').Trim();
        }


        /// <summary>
        /// 去掉byte数组前面size长度返回,主要用于解析去除包头用
        /// </summary>
        /// <param name="mainData">MainData</param>
        /// <param name="size">去除长度</param>
        /// <returns></returns>
        public static byte[] GetRidOfFrontBytes(byte[] mainData, int size)
        {
            int length = mainData.Length;
            if (length <= size)
                return null;
            byte[] data = new byte[length - size];
            Array.Copy(mainData, size, data, 0, length - size);
            //for (int i = size; i < length; i++)
            //data[i - size] = mainData[i];
            return data;
        }

        /// <summary>
        /// 通过字符串获取MD5值，返回32位字符串。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetMD5String(string str)
        {
            MD5 md5 = MD5.Create();
            byte[] data = Encoding.UTF8.GetBytes(str);
            byte[] data2 = md5.ComputeHash(data);

            return GetbyteToString(data2);
        }


        /// <summary>
        /// 将byte数组转换成string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static string GetbyteToString(byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 加密byte
        /// </summary>
        /// <returns></returns>
        public static byte[] EncodeByte(byte[] buffer)
        {
            //加密
            try
            {
                int nOutputLen = buffer.Length;
                byte[] pOutputBuffer = new byte[nOutputLen];
                if (Encrypt.encode(buffer, ref pOutputBuffer, (ushort)nOutputLen))
                {
                    GameUtilty.Info("加密成功!数据长度为:" + pOutputBuffer.Length);
                }

                if (nOutputLen != pOutputBuffer.Length)
                {
                    GameUtilty.Error("发送数据异常!");
                    return null;
                }

                return pOutputBuffer;
            }
            catch (Exception ex)
            {
                GameUtilty.Error("WebSocketZ:" + ex.ToString());
                return null;
            }
        }
        
        /// <summary>
        /// StructToBytes
        /// </summary>
        /// <param name="structure"></param>
        /// <returns></returns>
        public static byte[] StructToBytes(object structure)
        {
            Int32 size = Marshal.SizeOf(structure);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structure, buffer, false);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer,bytes,0,size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        
        /// <summary>
        /// byteToStruct
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="structType"></param>
        /// <returns></returns>
        public static T bytesToStruct<T>(byte[] bytes)
        {
            Int32 size = Marshal.SizeOf(typeof(T));
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure<T>(buffer);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

    }
}